package com.mike.bdb.ui.provider.tree;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * 树结构的节点描述
 * 不支持相同的子节点，内部子节点容器采用的是HashSet
 * @author <a href="zhaoming23@gmail.com"> Mike </a>
 * @version 1.0
 * 2011-4-22 下午4:34:32
 */
public class TreeNode {
	
	public static final String LEAF_NODE_SPLIT_CHAR = ":L:";

	public static final String	NODE_SPLIT_CHAR	= ":N:";
	
	/** 节点名称 */
	private String name;
	/** 子节点 */
	private Set<TreeNode> child;
	/** 父节点 */
	private TreeNode parent;

	/** TreeNode Constructor */
	public TreeNode(String nodeName, TreeNode parent) {
		if(null == nodeName || "".equals(nodeName.trim())) {
			name = String.valueOf(System.currentTimeMillis());
		} else {
			name = nodeName;
		}
		this.parent = parent;
		if(null != parent) {
			parent.addChildNode(this);
		}
	}

	/** Growing Don't support null TreeNode*/
	private void addChildNode(TreeNode node) {
		if(null == node) return;
		if(null == child) 
			child = Collections.newSetFromMap(new ConcurrentHashMap<TreeNode, Boolean>());
		if(!child.contains(node))
			child.add(node);
	}
	
	public String getName() {
		return name;
	}
	
	public Set<TreeNode> getChild() {
		return child;
	}
	
	public TreeNode getParent() {
		return parent;
	}
	
	public static boolean isLeaf(String name) {
		return name.contains(LEAF_NODE_SPLIT_CHAR);
	}
	
	public boolean isLeaf() {
		return null == child && !isRoot();
	}
	
	public boolean isRoot() {
		return null == parent;
	}
	
	public TreeNode getRoot() {
		if(null == getParent()) return this;
		return getParent().getRoot();
	}
	
	/**
	 * R#O#O#O::A
	 * #O#O::B
	 */
	@Override
	public String toString() {
		if(isLeaf()) {
			return getParent().toString() + LEAF_NODE_SPLIT_CHAR + getName();
		} else {
			if(isRoot()) {
				return getName();
			} else {
				return getParent().toString() + NODE_SPLIT_CHAR + getName();
			}
		}
	}

	@Override
	public boolean equals(Object obj) {
		boolean result = false;
		if(obj instanceof TreeNode) {
			TreeNode node = (TreeNode) obj;
			if(isRoot()) {
				result = (new EqualsBuilder()
				.append(name, node.getName()))
				.isEquals();
			} else {
				result = (new EqualsBuilder()
				.append(name, node.getName())
				.append(parent, node.parent))
				.isEquals();
			}
		}
		return result;
	}
	
	@Override
	public int hashCode() {
		if(isRoot()) {
			return new HashCodeBuilder(3, 7)
			.append(name)
			.toHashCode();
		} else {
			return new HashCodeBuilder(3, 7)
			.append(name)
			.append(parent)
			.toHashCode();
		}
	}
	
}
